#include "worker.h"
#include "../../db/common/common.h"
#include "../../log/systemLog/systemLog.h"
#include "../../trans_file_server/trans_file_server.h"
#include "../../tlv/tlv.h"

#include <stdlib.h>
#include <unistd.h>

int worker_list_init(worker_list_t *worker_list, int worker_count)
{
    if (worker_list == NULL || worker_count <= 0)
    {
        return SYSTEM_ERR_INVALID_ARGUMENT;
    }

    worker_list->workers = (pthread_t *)malloc(sizeof(pthread_t) * worker_count);
    if (worker_list->workers == NULL)
    {
        return SYSTEM_ERR_OUT_OF_MEMORY;
    }

    worker_list->worker_count = worker_count;
    return SYSTEM_ERR_OK;
}

// 工作线程执行的任务函数
void *worker_task(void *arg)
{
    // 先获取共享资源
    shared_data_t *shared_data = (shared_data_t *)arg;
    // 不断获取任务
    while (1)
    {
        // 加锁
        pthread_mutex_lock(&shared_data->queue_mutex);
        // 循环检查任务队列和退出标志
        while (shared_data->task_queue.size == 0 && shared_data->exit_flag != 1)
        {
            // 等待任务到来
            pthread_cond_wait(&shared_data->queue_cond, &shared_data->queue_mutex);
        }
        // 检查退出标志
        if (shared_data->exit_flag == 1)
        {
            pthread_mutex_unlock(&shared_data->queue_mutex);
            break; // 退出线程
        }
        // 从任务队列中取出一个任务
        task_node_t *task_node = NULL;
        int ret = dequeue_task(&shared_data->task_queue, &task_node);
        // 错误处理
        if (ret != SYSTEM_ERR_OK)
        {
            // 这里不应该发生错误，记录日志并继续
            DEQUEUE_TASK_CHECK(ret);
            pthread_mutex_unlock(&shared_data->queue_mutex);
            continue;
        }
        // 解锁
        pthread_mutex_unlock(&shared_data->queue_mutex);
        // 获取MYSQL连接
        ret = db_common_mysql_connect(&task_node->session->conn);
        if (ret != SYSTEM_ERR_OK)
        {
            SYSTEM_LOG_ERROR(ret, "Failed to connect to MySQL for user_id=%d", task_node->session->user_id);
            // 关闭连接并释放资源
            close(task_node->session->netfd);
            // TODO: 释放 session 相关资源
            free(task_node->session);
            free(task_node);
            continue;
        }
        // 处理任务
        tlv_msg_t long_msg;
        bzero(&long_msg, sizeof(tlv_msg_t));
        ret = tlv_recv(task_node->session->netfd, &long_msg);
        // 用户退出处理
        if (ret == 1)
        {
            // 关闭连接并释放资源
            if (task_node->session->conn != NULL)
            {
                mysql_close(task_node->session->conn);
            }
            close(task_node->session->netfd);
            free(task_node->session->pStack);
            free(task_node->session);
            free(task_node);
            continue;
        }
        switch (long_msg.hdr.type)
        {
        case CMD_PUTS_REQ:
            printf("Worker handling PUTS request for user_id=%d\n", task_node->session->user_id);
            ret = put_file_to_serv(long_msg, task_node->session);
            printf("PUTS request handled with return code %d\n", ret);
            break;
        case CMD_GETS_REQ:
            printf("Worker handling GETS request for user_id=%d\n", task_node->session->user_id);
            ret = get_file_from_serv(long_msg, task_node->session);
            printf("GETS request handled with return code %d\n", ret);
            break;
        }
        // 处理完任务后释放传入的资源
        // 关闭MYSQL连接
        if (task_node->session->conn != NULL)
        {
            mysql_close(task_node->session->conn);
        }
        // 释放 session 相关资源
        close(task_node->session->netfd);
        free(task_node->session->pStack);
        free(task_node->session);
        free(task_node);
    }

    pthread_exit(NULL);
}

int make_workers(worker_list_t *worker_list, shared_data_t *shared_data)
{
    // 参数检查
    if (worker_list == NULL || shared_data == NULL)
    {
        return SYSTEM_ERR_INVALID_ARGUMENT;
    }
    // 创建工作线程
    for (int i = 0; i < worker_list->worker_count; i++)
    {
        int ret = pthread_create(&worker_list->workers[i], NULL, worker_task, (void *)shared_data);
        if (ret != 0)
        {
            return SYSTEM_ERR_WORKER_THREAD_CREATE;
        }
    }

    return SYSTEM_ERR_OK;
}